package spring.cloud.tasks.executor.api;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import spring.cloud.tasks.executor.name_space.executor.Executor;
import spring.cloud.tasks.executor.name_space.executor.task.task_item.TaskItemExecute;
import spring.cloud.tasks.executor.name_space.executor.tasks_runtime_info.task_item_assign.TaskIdToTaskInstanceIdToTaskItemIndexListMapMap;
import spring.cloud.tasks.executor.name_space.executor.tasks_runtime_info.task_item_execute.TaskItemExecuteRuntimeContext;

import java.util.Date;

@Slf4j
@Setter
@Getter
public abstract class Task {
    /**
     * Scope("prototype")
     */
    public static final String scope_prototype = "prototype";
    private TaskItemExecute taskItemExecute;
    private String taskId;
    private Integer taskItemIndex;
    private String taskItemValue;
    private volatile Date lastReportDate = new Date();

    /**
     * @param taskItemExecute
     * @param taskId
     * @param taskItemIndex
     * @param taskItemValue
     */
    public void init(TaskItemExecute taskItemExecute, String taskId, Integer taskItemIndex, String taskItemValue) {
        this.taskItemExecute = taskItemExecute;
        this.taskId = taskId;
        this.taskItemIndex = taskItemIndex;
        this.taskItemValue = taskItemValue;
    }

    /**
     * @throws InterruptedException 该异常代表程序应该主动结束后续代码的执行
     */
    public abstract void execute() throws InterruptedException;

    public void updateLastReportDate() {
        lastReportDate = new Date();
    }

    /**
     * 状态汇报以及任务健康检测
     *
     * @param stage 执行阶段
     * @throws InterruptedException 该异常代表程序应该主动结束后续代码的执行
     */
    public void watchDog(String stage) throws InterruptedException {
        if (isNeedInterrupt()) {
            throw new InterruptedException();
        }
        if (log.isDebugEnabled()) {
            log.debug("当前运行阶段为:" + stage);
        }
        updateLastReportDate();
    }

    public boolean isNeedInterrupt() {
        if (Executor.getNeedStopFlag()) {
            return true;
        }
        if (taskItemExecute.needStop) {//spring.cloud.tasks.executor.executor.task.task_item.TaskItemExecuteTaskKill.kill
            return true;
        }
        TaskItemExecuteRuntimeContext taskItemExecuteRuntimeContext = taskItemExecute.getTaskItemExecuteRuntimeContext();
        if (taskItemExecuteRuntimeContext == null) {
            return true;
        }
        if (taskItemExecuteRuntimeContext.needStop) {
            return true;
        }
        TaskIdToTaskInstanceIdToTaskItemIndexListMapMap taskIdToTaskInstanceIdToTaskItemIndexListMapMap = taskItemExecute.getTaskIdToTaskInstanceIdToTaskItemIndexListMapMap();
        boolean isAssigned = taskIdToTaskInstanceIdToTaskItemIndexListMapMap.isAssigned(taskItemExecuteRuntimeContext);
        return !isAssigned;
    }

}
